/*
 * BerryRavindran.cpp
 *
 *  Created on: 27-08-2013
 *      Author: Krzychu
 */

#include "BerryRavindran.h"

#include "../Structures/Config.h"

#include <stdio.h>
#include <string.h>

#define ASIZE 255

BerryRavindran::BerryRavindran()
{

}

BerryRavindran::~BerryRavindran()
{

}

std::string BerryRavindran::getName()
{
	return "Berry Ravindran";
}

int** preBrBc(std::string pattern)
{
	int** result = new int*[ASIZE];
	int patternSize = pattern.size();

	for (int a = 0; a < ASIZE; ++a)
	{
		result[a] = new int[ASIZE];
		for (int b = 0; b < ASIZE; ++b)
		{
			result[a][b] = patternSize + 2;
		}
	}
	for (int a = 0; a < ASIZE; ++a)
	{
		result[a][pattern[0]] = patternSize + 1;
	}
	for (int i = 0; i < patternSize - 1; ++i)
	{
		result[pattern[i]][pattern[i + 1]] = patternSize - i;
	}
	for (int a = 0; a < ASIZE; ++a)
	{
		result[pattern[patternSize - 1]][a] = 1;
	}

	return result;
}

searchResult BerryRavindran::execute(std::string text, std::string pattern)
{
	searchResult result;
	result.iterationsTaken = 0;

	int textSize = text.size();
	int patternSize = pattern.size();
	const char* textChar = text.c_str();
	const char* patternChar = pattern.c_str();

	/* Preprocessing */
	int** brBc = preBrBc(pattern);

	/* Searching */
	int j = 0;
	while (j <= textSize - patternSize)
	{
		result.iterationsTaken++;
		if (memcmp(patternChar, textChar + j, patternSize) == 0)
		{
			result.positionsFound.push_back(j);
			if (Config::getInstance()->getFindOneOccurence())
			{
				return result;
			}
		}
		j += brBc[text[j + patternSize]][text[j + patternSize + 1]];
	}

	return result;
}
